package com.exam.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.exam.exceptions.BizIllegalException;
import com.exam.pojo.domain.Question;
import com.exam.pojo.domain.QuestionCategory;
import com.exam.pojo.domain.User;
import com.exam.pojo.dto.CollErrorDTO;
import com.exam.pojo.dto.UserDTO;
import com.exam.pojo.vo.QuestionCategoryVO;
import com.exam.pojo.vo.UserVO;
import com.exam.service.IUserService;
import com.exam.utils.CollUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements IUserService {

    private final MongoTemplate mongoTemplate;

    @Override
    public void addUser(UserDTO dto) {
        User user = BeanUtil.toBean(dto, User.class);
        mongoTemplate.save(user);
    }

    @Override
    public UserVO findById(String uuid) {
        User user = mongoTemplate.findById(uuid, User.class);
        if(user==null){
            return null;
        }
        UserVO userVO = BeanUtil.toBean(user, UserVO.class);
        List<Long> errorQuestionIds = user.getErrorQuestionIds();
        if(CollUtils.isNotEmpty(errorQuestionIds)){
            List<QuestionCategory> cates = mongoTemplate.findAll(QuestionCategory.class);
            Map<String, QuestionCategory> map = CollUtils.fieldValueMap(cates, "id");
            AggregationResults<QuestionCategoryVO> result = mongoTemplate.aggregate(Aggregation.newAggregation(
                    Aggregation.match(Criteria.where("id").in(errorQuestionIds)),
                    Aggregation.group("cateId").count().as("counts")
            ), Question.class, QuestionCategoryVO.class);
            List<QuestionCategoryVO> voList = result.getMappedResults();
            if(CollUtils.isNotEmpty(voList)){
                voList = voList.stream().sorted(Comparator.comparing(QuestionCategoryVO::getNum,Comparator.reverseOrder()))
                        .collect(Collectors.toList());
                QuestionCategoryVO vo = voList.get(0);
                QuestionCategory cate = map.get(vo.getId());
                BeanUtil.copyProperties(cate,vo);
                userVO.setWeakCate(vo);
            }
        }
        return userVO;
    }

    @Override
    public void handleQuestion(CollErrorDTO dto) {
        Integer type = dto.getType();
        Query query = Query.query(Criteria.where("id").is(dto.getUuid()));
        Update update = new Update();
        switch (type){
            case 1:
                //新增收藏
                mongoTemplate.updateFirst(query,update.addToSet("collectQuestionIds",dto.getQuestionId()), User.class);
                break;
            case 2:
                //删除收藏
                mongoTemplate.updateFirst(query,update.pull("collectQuestionIds",dto.getQuestionId()), User.class);
                break;
            case 3:
                //删除错误题目
                mongoTemplate.updateFirst(query,update.pull("errorQuestionIds",dto.getQuestionId()), User.class);
                break;
            case 4:
                //清空错误题目
                mongoTemplate.updateFirst(query,update.set("errorQuestionIds", CollUtils.emptyList()), User.class);
                break;
            default:
                throw new BizIllegalException("操作参数错误");
        }
    }
}
